#include <esp_log.h>
#include <esp_err.h>
#include <string>
#include <cstdlib>
#include <cstring>

#include "display.h"
#include "board.h"
#include "application.h"
#include "font_awesome_symbols.h"
#include "audio_codec.h"
#include "settings.h"
#include "assets/lang_config.h"
#include "lvgl.h" // 添加这个头
#define TAG "Display"

Display::Display()
{
    // Notification timer
    esp_timer_create_args_t notification_timer_args = {
        .callback = [](void *arg)
        {
            Display *display = static_cast<Display *>(arg);
            DisplayLockGuard lock(display);
            lv_obj_add_flag(display->notification_label_, LV_OBJ_FLAG_HIDDEN);
            lv_obj_clear_flag(display->status_label_, LV_OBJ_FLAG_HIDDEN);
        },
        .arg = this,
        .dispatch_method = ESP_TIMER_TASK,
        .name = "notification_timer",
        .skip_unhandled_events = false,
    };
    ESP_ERROR_CHECK(esp_timer_create(&notification_timer_args, &notification_timer_));

    // Create a power management lock
    auto ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "display_update", &pm_lock_);
    if (ret == ESP_ERR_NOT_SUPPORTED)
    {
        ESP_LOGI(TAG, "Power management not supported");
    }
    else
    {
        ESP_ERROR_CHECK(ret);
    }

    // 初始化消息按钮相关成员变量
    // message_button_container_ = nullptr;
    // message_button_label_ = nullptr;
    // message_button_timer_ = nullptr;


    // 创建消息按钮定时器
    esp_timer_create_args_t message_button_timer_args = {
        .callback = [](void *arg)
        {
            Display *display = static_cast<Display *>(arg);
            DisplayLockGuard lock(display);
            // 启动隐藏动画
            lv_anim_start(&display->message_button_hide_anim_);
            // 在动画结束后隐藏按钮容器
            lv_obj_add_flag(display->message_button_container_, LV_OBJ_FLAG_HIDDEN);
        },
        .arg = this,
        .dispatch_method = ESP_TIMER_TASK,
        .name = "message_button_timer",
        .skip_unhandled_events = false,
    };
    ESP_ERROR_CHECK(esp_timer_create(&message_button_timer_args, &message_button_timer_));
}

Display::~Display()
{

    if (message_button_timer_ != nullptr)
    {
        esp_timer_stop(message_button_timer_);
        esp_timer_delete(message_button_timer_);
    }

    if (message_button_container_ != nullptr)
    {
        lv_obj_del(message_button_container_);
    }

    if (notification_timer_ != nullptr)
    {
        esp_timer_stop(notification_timer_);
        esp_timer_delete(notification_timer_);
    }

    if (network_label_ != nullptr)
    {
        lv_obj_del(network_label_);
        lv_obj_del(notification_label_);
        lv_obj_del(status_label_);
        lv_obj_del(mute_label_);
        lv_obj_del(battery_label_);
        lv_obj_del(emotion_label_);
    }
    if (low_battery_popup_ != nullptr)
    {
        lv_obj_del(low_battery_popup_);
    }
    if (pm_lock_ != nullptr)
    {
        esp_pm_lock_delete(pm_lock_);
    }
}

void Display::SetStatus(const char *status)
{
    DisplayLockGuard lock(this);
    if (status_label_ == nullptr)
    {
        return;
    }
    lv_label_set_text(status_label_, status);
    lv_obj_clear_flag(status_label_, LV_OBJ_FLAG_HIDDEN);
    lv_obj_add_flag(notification_label_, LV_OBJ_FLAG_HIDDEN);

    last_status_update_time_ = std::chrono::system_clock::now();
}

void Display::ShowNotification(const std::string &notification, int duration_ms)
{
    ShowNotification(notification.c_str(), duration_ms);
}

void Display::ShowNotification(const char *notification, int duration_ms)
{
    DisplayLockGuard lock(this);
    if (notification_label_ == nullptr)
    {
        return;
    }
    lv_label_set_text(notification_label_, notification);
    lv_obj_clear_flag(notification_label_, LV_OBJ_FLAG_HIDDEN);
    lv_obj_add_flag(status_label_, LV_OBJ_FLAG_HIDDEN);

    esp_timer_stop(notification_timer_);
    ESP_ERROR_CHECK(esp_timer_start_once(notification_timer_, duration_ms * 1000));
}

void Display::UpdateStatusBar(bool update_all)
{
    auto &app = Application::GetInstance();
    auto &board = Board::GetInstance();
    auto codec = board.GetAudioCodec();

    // Update mute icon
    {
        DisplayLockGuard lock(this);
        if (mute_label_ == nullptr)
        {
            return;
        }

        // 如果静音状态改变，则更新图标
        if (codec->output_volume() == 0 && !muted_)
        {
            muted_ = true;
            lv_label_set_text(mute_label_, FONT_AWESOME_VOLUME_MUTE);
        }
        else if (codec->output_volume() > 0 && muted_)
        {
            muted_ = false;
            lv_label_set_text(mute_label_, "");
        }
    }

    // Update time
    // if (app.GetDeviceState() == kDeviceStateIdle)
    // {
    //     if (last_status_update_time_ + std::chrono::seconds(10) < std::chrono::system_clock::now())
    //     {
    //         // Set status to clock "HH:MM"
    //         time_t now = time(NULL);
    //         struct tm *tm = localtime(&now);
    //         // Check if the we have already set the time
    //         if (tm->tm_year >= 2025 - 1900)
    //         {
    //             char time_str[16];
    //             strftime(time_str, sizeof(time_str), "%H:%M  ", tm);
    //             SetStatus(time_str);
    //         }
    //         else
    //         {
    //             ESP_LOGW(TAG, "System time is not set, tm_year: %d", tm->tm_year);
    //         }
    //     }
    // }

      // Update time  
    if (app.GetDeviceState() == kDeviceStateIdle) {  
        if (last_status_update_time_ + std::chrono::seconds(10) < std::chrono::system_clock::now()) {  
            // Set status to clock with weekday "周X HH:MM"  
            time_t now = time(NULL);  
            struct tm* tm = localtime(&now);  
            // Check if the we have already set the time  
            if (tm->tm_year >= 2025 - 1900) {  
                // Get weekday string from language config  
                const char* weekday_strings[] = {  
                    Lang::Strings::WEEKDAY_0, // Sunday  
                    Lang::Strings::WEEKDAY_1, // Monday  
                    Lang::Strings::WEEKDAY_2, // Tuesday  
                    Lang::Strings::WEEKDAY_3, // Wednesday  
                    Lang::Strings::WEEKDAY_4, // Thursday  
                    Lang::Strings::WEEKDAY_5, // Friday  
                    Lang::Strings::WEEKDAY_6  // Saturday  
                };  
                  
                char time_str[32];  
                snprintf(time_str, sizeof(time_str), "%s %02d:%02d",   
                        weekday_strings[tm->tm_wday], tm->tm_hour, tm->tm_min);  
                SetStatus(time_str);  
            } else {  
                ESP_LOGW(TAG, "System time is not set, tm_year: %d", tm->tm_year);  
            }  
        }  
    }

    esp_pm_lock_acquire(pm_lock_);
    // 更新电池图标
    int battery_level;
    bool charging, discharging;
    const char *icon = nullptr;
    if (board.GetBatteryLevel(battery_level, charging, discharging))
    {
        if (charging)
        {
            icon = FONT_AWESOME_BATTERY_CHARGING;
        }
        else
        {
            const char *levels[] = {
                FONT_AWESOME_BATTERY_EMPTY, // 0-19%
                FONT_AWESOME_BATTERY_1,     // 20-39%
                FONT_AWESOME_BATTERY_2,     // 40-59%
                FONT_AWESOME_BATTERY_3,     // 60-79%
                FONT_AWESOME_BATTERY_FULL,  // 80-99%
                FONT_AWESOME_BATTERY_FULL,  // 100%
            };
            icon = levels[battery_level / 20];
        }
        DisplayLockGuard lock(this);
        if (battery_label_ != nullptr && battery_icon_ != icon)
        {
            battery_icon_ = icon;
            lv_label_set_text(battery_label_, battery_icon_);
        }

        if (low_battery_popup_ != nullptr)
        {
            if (strcmp(icon, FONT_AWESOME_BATTERY_EMPTY) == 0 && discharging)
            {
                if (lv_obj_has_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN))
                { // 如果低电量提示框隐藏，则显示
                    lv_obj_clear_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN);
                    app.PlaySound(Lang::Sounds::P3_LOW_BATTERY);
                }
            }
            else
            {
                // Hide the low battery popup when the battery is not empty
                if (!lv_obj_has_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN))
                { // 如果低电量提示框显示，则隐藏
                    lv_obj_add_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN);
                }
            }
        }
    }

    // 每 10 秒更新一次网络图标
    static int seconds_counter = 0;
    if (update_all || seconds_counter++ % 10 == 0)
    {
        // 升级固件时，不读取 4G 网络状态，避免占用 UART 资源
        auto device_state = Application::GetInstance().GetDeviceState();
        static const std::vector<DeviceState> allowed_states = {
            kDeviceStateIdle,
            kDeviceStateStarting,
            kDeviceStateWifiConfiguring,
            kDeviceStateListening,
            kDeviceStateActivating,
        };
        if (std::find(allowed_states.begin(), allowed_states.end(), device_state) != allowed_states.end())
        {
            icon = board.GetNetworkStateIcon();
            if (network_label_ != nullptr && icon != nullptr && network_icon_ != icon)
            {
                DisplayLockGuard lock(this);
                network_icon_ = icon;
                lv_label_set_text(network_label_, network_icon_);
            }
        }
    }

    esp_pm_lock_release(pm_lock_);
}

void Display::SetEmotion(const char *emotion)
{
    struct Emotion
    {
        const char *icon;
        const char *text;
    };

    static const std::vector<Emotion> emotions = {
        {FONT_AWESOME_EMOJI_NEUTRAL, "neutral"},
        {FONT_AWESOME_EMOJI_HAPPY, "happy"},
        {FONT_AWESOME_EMOJI_LAUGHING, "laughing"},
        {FONT_AWESOME_EMOJI_FUNNY, "funny"},
        {FONT_AWESOME_EMOJI_SAD, "sad"},
        {FONT_AWESOME_EMOJI_ANGRY, "angry"},
        {FONT_AWESOME_EMOJI_CRYING, "crying"},
        {FONT_AWESOME_EMOJI_LOVING, "loving"},
        {FONT_AWESOME_EMOJI_EMBARRASSED, "embarrassed"},
        {FONT_AWESOME_EMOJI_SURPRISED, "surprised"},
        {FONT_AWESOME_EMOJI_SHOCKED, "shocked"},
        {FONT_AWESOME_EMOJI_THINKING, "thinking"},
        {FONT_AWESOME_EMOJI_WINKING, "winking"},
        {FONT_AWESOME_EMOJI_COOL, "cool"},
        {FONT_AWESOME_EMOJI_RELAXED, "relaxed"},
        {FONT_AWESOME_EMOJI_DELICIOUS, "delicious"},
        {FONT_AWESOME_EMOJI_KISSY, "kissy"},
        {FONT_AWESOME_EMOJI_CONFIDENT, "confident"},
        {FONT_AWESOME_EMOJI_SLEEPY, "sleepy"},
        {FONT_AWESOME_EMOJI_SILLY, "silly"},
        {FONT_AWESOME_EMOJI_CONFUSED, "confused"}};

    // 查找匹配的表情
    std::string_view emotion_view(emotion);
    auto it = std::find_if(emotions.begin(), emotions.end(),
                           [&emotion_view](const Emotion &e)
                           { return e.text == emotion_view; });

    DisplayLockGuard lock(this);
    if (emotion_label_ == nullptr)
    {
        return;
    }

    // 如果找到匹配的表情就显示对应图标，否则显示默认的neutral表情
    if (it != emotions.end())
    {
        lv_label_set_text(emotion_label_, it->icon);
    }
    else
    {
        lv_label_set_text(emotion_label_, FONT_AWESOME_EMOJI_NEUTRAL);
    }
}

void Display::SetIcon(const char *icon)
{
    DisplayLockGuard lock(this);
    if (emotion_label_ == nullptr)
    {
        return;
    }
    lv_label_set_text(emotion_label_, icon);
}

void Display::SetPreviewImage(const lv_img_dsc_t *image)
{
    // Do nothing
}

void Display::SetChatMessage(const char *role, const char *content)
{
    DisplayLockGuard lock(this);
    if (chat_message_label_ == nullptr)
    {
        return;
    }
    lv_label_set_text(chat_message_label_, content);
}

void Display::SetMusicInfo(const char *song_name)
{
    // 默认实现：对于非微信模式，将歌名显示在聊天消息标签中
    DisplayLockGuard lock(this);
    if (chat_message_label_ == nullptr)
    {
        return;
    }
    if (song_name != nullptr && strlen(song_name) > 0)
    {
        std::string music_text = "";
        music_text += song_name;
        lv_label_set_text(chat_message_label_, music_text.c_str());
    }
    else
    {
        lv_label_set_text(chat_message_label_, "");
    }
}

void Display::SetTheme(const std::string &theme_name)
{
    current_theme_name_ = theme_name;
    Settings settings("display", true);
    settings.SetString("theme", theme_name);
}

void Display::SetPowerSaveMode(bool on)
{
    if (on)
    {
        SetChatMessage("system", "");
        SetEmotion("sleepy");
    }
    else
    {
        SetChatMessage("system", "");
        SetEmotion("neutral");
    }
}

void Display::ShowMessageButton(const char *text, int duration_ms)
{
    DisplayLockGuard lock(this);
    if (message_button_container_ == nullptr || message_button_label_ == nullptr)
    {
        return;
    }

    // 设置消息按钮文本
    lv_label_set_text(message_button_label_, text);

    // 获取屏幕高度
    // lv_coord_t screen_height = lv_disp_get_ver_res(NULL);
    // lv_coord_t container_height = lv_obj_get_height(message_button_container_);

    // // 设置初始位置（屏幕外底部）
    // lv_obj_set_y(message_button_container_, screen_height);
    lv_obj_clear_flag(message_button_container_, LV_OBJ_FLAG_HIDDEN);


    // 启动显示动画
    // lv_anim_start(&message_button_show_anim_);

    // 停止之前的定时器
    esp_timer_stop(message_button_timer_);

    // 启动定时器，在指定时间后触发隐藏动画
    ESP_ERROR_CHECK(esp_timer_start_once(message_button_timer_, duration_ms * 1000));
}

void Display::ShowMessageButton(std::string text, int duration_ms)
{
    // 直接调用const char*版本的重载函数
    ShowMessageButton(text.c_str(), duration_ms);
}